/**
 * Persistent Java User object
 */
package com.excilys.model;

import java.io.Serializable;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

/**
 * POJO User
 * 
 * @author excilys dev : VP
 * @version 1.0
 * 
 */
@SuppressWarnings("serial")
@Entity
public class User implements UserDetails, Serializable {

	// implements Serializable is necessary if User object is part of a session

	@Id
	@GeneratedValue
	private long userId;
	private String userFirstName;
	private String userLastName;
	@Column(unique = true)
	private String userLogin;
	private String userPassword;
	private String userRole;
	@OneToMany(mappedBy = "accountUser", fetch = FetchType.LAZY)
	private List<Account> userListAccounts;
	@JoinTable(name = "User_TargetAccounts")
	@ManyToMany(fetch = FetchType.LAZY)
	private List<Account> userTargetAccounts;

	private boolean enabled;

	// ------------------------------------------------------------
	// ------------------------------------------------------------
	// ------------------------------------------------------------

	/**
	 * Default constructor needed. Loading Object and proxy generation. Avoid
	 * Exception type InstantiationException
	 */
	public User() {
		super();
	}

	public User(String firstName, String lastName, String login, String password, String role, boolean enabled) {
		super();
		this.userFirstName = firstName;
		this.userLastName = lastName;
		this.userLogin = login;
		this.userPassword = password;
		this.userRole = role;
		this.enabled = enabled;
	}

	// ------------------------------------------------------------
	// ------------------------------------------------------------
	// ------------------------------------------------------------

	public String toString() {
		String res = "Firstname = " + userFirstName + " / Lastname = " + userLastName + " / Login = " + userLogin;
		return res;
	}

	public void addTargetAccount(Account paccount) {

		boolean contains = false;
		int i = 0;
		while (i < this.userTargetAccounts.size() && !contains) {
			if (this.userTargetAccounts.get(i).getAccountId() == paccount.getAccountId()) {
				contains = true;
			}
			i++;
		}

		if (!contains) {
			userTargetAccounts.add(paccount);
		}
	}

	// ------------------------------------------------------------
	// ------------------------------------------------------------
	// ------------------------------------------------------------

	public long getUserId() {
		return userId;
	}

	public void setUserId(long userId) {
		this.userId = userId;
	}

	public String getUserFirstName() {
		return userFirstName;
	}

	public void setUserFirstName(String userFirstName) {
		this.userFirstName = userFirstName;
	}

	public String getUserLastName() {
		return userLastName;
	}

	public void setUserLastName(String userLastName) {
		this.userLastName = userLastName;
	}

	public String getUserLogin() {
		return userLogin;
	}

	public void setUserLogin(String userLogin) {
		this.userLogin = userLogin;
	}

	public String getUserPassword() {
		return userPassword;
	}

	public void setUserPassword(String userPassword) {
		this.userPassword = userPassword;
	}

	public String getUserRole() {
		return userRole;
	}

	public void setUserRole(String userRole) {
		this.userRole = userRole;
	}

	public List<Account> getUserListAccounts() {
		return userListAccounts;
	}

	public void setUserListAccounts(List<Account> userListAccounts) {
		this.userListAccounts = userListAccounts;
	}

	public List<Account> getUserTargetAccounts() {
		return userTargetAccounts;
	}

	public void setUserTargetAccounts(List<Account> userTargetAccounts) {
		this.userTargetAccounts = userTargetAccounts;
	}

	public boolean isEnabled() {
		return enabled;
	}

	public void setEnabled(boolean enabled) {
		this.enabled = enabled;
	}

	@Override
	public Collection<GrantedAuthority> getAuthorities() {
		return null;
	}

	@Override
	public String getPassword() {
		return this.userPassword;
	}

	@Override
	public String getUsername() {
		return this.userLogin;
	}

	@Override
	public boolean isAccountNonExpired() {
		return true;
	}

	@Override
	public boolean isAccountNonLocked() {
		return true;
	}

	@Override
	public boolean isCredentialsNonExpired() {
		return true;
	}

	public boolean containAccountOfId(long accountId) {
		boolean res = false;
		Iterator<Account> i = getUserListAccounts().iterator();
		while (i.hasNext() && !res) {
			if (i.next().getAccountId() == accountId) {
				res = true;
			}
		}
		return res;
	}

	public boolean containAccountOfName(String accountName) {
		boolean res = false;
		Iterator<Account> i = getUserListAccounts().iterator();
		while (i.hasNext() && !res) {
			Account a = i.next();
			if (a.getAccountName().equals(accountName)) {
				res = true;
			}
		}
		return res;
	}

	@Override
	public int hashCode() {
		int result = 7;
		final int multiplier = 17;
		result = multiplier * result + (userLogin == null ? 0 : userLogin.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (obj == this)
			return true;
		if (obj instanceof User) {
			User other = (User) obj;

			if (userLogin != other.userLogin) {
				if (userLogin == null || !userLogin.equals(other.userLogin))
					return false;
			}
			return true;
		}
		return false;
	}

}
